<?php

namespace XWAM\Addon\PXCallSystem\Controller;

/**
 * 运行状态控制器
 *
 * @author Alen
 * @since 1.0 2014-6-19 by sutroon
 */
class StatusController extends AppbaseController {

    /**
     * 中继状态表
     * @since 2014-9-15 by sutroon; 
     * @since 2015-5-15 SoChishun ReFactoring
     */
    public function trunk_status() {
        $this->display();
    }

    public function get_trunk_status_list_json() {
        $trunkName = I('trunkName');
        $channels = AddonD('AgiManager')->cli_core_show_channels_concise(5);
        $this->print_array($channels);
        $siteId_trunks = M('tcti_trunk')->cache(true)->getField('account, siteID', true);
        $siteId_Seats = M('tuser_member')->cache(true)->getField('extensionNumber,siteID', true);
        $icon_dir = C('TMPL_PARSE_STRING.__THEME__') . 'Images';
        $arrfy = array('Up' => "<img data-sort='1' src='$icon_dir/InUse.png' width='17' height='17' alt='talk' />通话", 'Ringing' => "<img data-sort='2' src='$icon_dir/Ringing.png' alt='ring' />振铃", 'Answer' => "<img data-sort='2' src='$icon_dir/Answer.png' alt='answer' />应答", 'Down' => "<img data-sort='3' src='$icon_dir/Idle.png' alt='call' />呼叫");
        $arrOut = array();
        foreach ($channels as $row) {
            $account = $row['UserTrunk'];
            if ($trunks && array_key_exists($account, $trunks)) {
                if (!$trunkName || ($trunkName && $account == $trunkName)) {
                    
                }
                $n++;
            }
            $strState = $row['UserState'];
            if (array_key_exists($strState, $arrfy)) {
                $strState = $arrfy[$strState];
                $strState.=' [<a href="' . AddonU('CtiManager/channel_handup?delogin=1&channel=' . str_replace('/', '{xg}', $row['Channel'])) . '" class="extension-handup" onclick="return handup(this);">挂断</a>]';
            }
            $siteID = '';
            if ($account && $siteId_trunks && array_key_exists($account, $siteId_trunks)) {
                $siteID = $siteId_trunks[$account];
            }
            if (!$siteID && $row['UserExten'] && $siteId_Seats && array_key_exists($row['UserExten'], $siteId_Seats)) {
                $siteID = $siteId_Seats[$row['UserExten']];
            }
            if ($trunkName && $account == $trunkName) {
                $arrOut[] = array('trunk' => $account, 'caller' => $row['UserCaller'], 'called' => $row['UserCalled'], 'state' => $strState, 'duration' => $row['UserDuration'], 'siteID' => $siteID, 'siteIDText' => get_siteID_text($siteID));
                continue;
            }
            $arrOut[] = array('trunk' => $account, 'caller' => $row['UserCaller'], 'called' => $row['UserCalled'], 'state' => $strState, 'duration' => $row['UserDuration'], 'siteID' => $siteID, 'siteIDText' => get_siteID_text($siteID));
        }
        // format end
        if (!$this->isSuperAdmin) {
            $siteID = $this->loginData['siteID'];
            $n = count($arrOut);
            for ($i = 0; $i < $n; $i++) {
                if ($arrOut[$i]['siteID'] !== $siteID) {
                    unset($arrOut[$i]);
                }
            }
        }
// 统计
        $sumdata = array('ring' => 0, 'talk' => 0, 'down' => 0, 'answer' => 0);
        $arrsort_state = array();
        foreach ($arrOut as $key => $row) {
            $arrsort_state[$key]['state'] = $row['state'];
            if (strpos($row['state'], "alt='talk'") !== false) {
                $sumdata['talk'] ++;
            } else if (strpos($row['state'], "alt='ring'") !== false) {
                $sumdata['ring'] ++;
            } else if (strpos($row['state'], "alt='call'") !== false) {
                $sumdata['down'] ++;
            } else if (strpos($row['state'], "alt='answer'") !== false) {
                $sumdata['answer'] ++;
            }
        }
        $strsum = '<span class="status-info"><span class="blue">呼叫总数<em>' . array_sum($sumdata) . '</em></span><span class="orange">呼叫中<em>' . $sumdata['down'] . '</em></span><span class="red">振铃中<em>' . $sumdata['ring'] . '</em></span><span class="dark-red">应答中<em>' . $sumdata['answer'] . '</em></span><span>通话中<em>' . $sumdata['talk'] . '</em></span></span>';
        array_multisort($arrsort_state, SORT_ASC, $arrOut);
        $this->ajaxReturn(array('total' => count($arrOut), 'rows' => $arrOut, 'sum' => $strsum));
    }

    public function extension_status() {
        $this->display();
    }

    /**
     * 分机在线状态
     * @since 1.0 2014-9-10 by sutroon
     *      1.1 2014-10-30 分机状态改为分机在线状态
     */
    public function get_extension_status_list_json() {
        $arrOut = $this->get_extension_status_data($strsum);
        $this->ajaxReturn(array('total' => count($arrOut), 'rows' => $arrOut, 'sum' => $strsum));
    }

    public function extension_talk_status() {
        $this->display();
    }

    /**
     * 分机通话状态
     * 分机号码、状态、持续时间，通话号码（从中继读取），操作（监听、转移等）
     */
    public function get_extension_talk_status_list_json() {
        $arrOut = $this->get_extension_status_data($strsum);
        $this->ajaxReturn(array('total' => count($arrOut), 'rows' => $arrOut, 'sum' => $strsum));
    }

// 队列状态
    public function acdno_status() {
        $tsid = I('tsid');
        $tpl = $tsid ? 'acdno_status_strategy' : '';
        $arr_outqueues = false;
// 外呼模式 - 队列监控
        if ($tsid) {
            $data = M('tcti_task_strategy')->field('speedMode, speed, trunkName, outQueue, outParam')->find($tsid);
            $this->assign('buttons', $this->get_speed_control($tsid, $data['speedMode'], $data['speed'], $data['trunkName']));
            $this->assign('tsid', $tsid);
            $outqueues = $data['outParam'];
            if (false !== strpos($outqueues, ':')) {
                $arrOutQueues = sofn_string_params_to_array($outqueues, ':', ';');
                if (false !== $arrOutQueues) {
                    $arr_outqueues = array_values($arrOutQueues);
                }
            }
            if ($data['outQueue']) {
                $arr_outqueues[] = $data['outQueue'];
            }

            if (!$arr_outqueues) {
                if (I('display') == 'content') {
                    echo '<br />没有队列.<br />';
                } else {
                    $this->assign('list', '<br />没有队列.<br />');
                    $this->display($tpl);
                }
                exit;
            }
        }
// 队列管理-状态管理
        $queue = I('queue');
        if ($queue) {
            $arr_outqueues[] = $queue;
        }

        $str = $this->SCommandResult('queue show', I('force') == '1' ? 0 : 10);
// format begin
        $arr = preg_split("/[\n]+/", trim($str));
        $arrOut = array();
        $i = 0;

        $queues = S('queues');
        if (!$queues) {
            $queues = M()->query('select extension, siteID from tcti_acd_queue');
            S('queues', $queues, array('expire' => 15));
        }
        foreach ($arr as $row) {
            if (strpos($row, ' strategy ') === false) {
                $arrOut[$i - 1]['sub'][] = $row;
            } else {
                $arrOut[$i] = array('queue' => substr($row, 0, strpos($row, ' ')), 'content' => $row, 'siteID' => '');
                foreach ($queues as $rqueue) {
                    if ($arrOut[$i]['queue'] == $rqueue['extension']) {
                        $arrOut[$i]['siteID'] = $rqueue['siteID'];
                    }
                }
                $i++;
            }
        }
        if (!$this->isSuperAdmin) {
            $n = count($arrOut);
            for ($i = 0; $i < $n; $i++) {
                if ($arrOut[$i]['siteID'] !== $this->loginData['siteID']) {
                    unset($arrOut[$i]);
                }
            }
        }
        $arrOut = sofn_set_site_id_text($arrOut);
        $arrfy_content = array('(max unlimited) in' => '(无限制)在', 'strategy' => '振铃规则', 'ringall' => '呼叫所有', 'rrmemory' => '记忆呼叫', 'random' => '随机');
        $arrfy_item = array('No Members' => '没有分机', 'No Callers' => '没有来电', 'Members' => '分机', 'Callers' => '来电', '(dynamic)' => '', '(Unavailable)' => '不可用', 'Not in use' => '空闲', 'has taken no calls yet' => '没有任何来电', 'last was' => '距离上次通话时间', 'secs ago' => '秒', 'wait:' => '等待:', 'Invalid' => '无效', 'In use' => '<span style="color:#F00;">通话中U</span>', 'Ringing' => '振铃中', 'ringinuse' => '', 'Busy' => '<span style="color:#F00;">通话中B</span>', '(paused)' => '<em style="color:#F90">(示忙)</em>');
// $arrfy_item = array('No Members' => '没有分机', 'No Callers' => '没有来电', 'Members' => '分机', 'Callers' => '来电', 'enabled' => '可用', 'dynamic' => '动态', 'Unavailable' => '不可用', 'Not in use' => '空闲', 'has taken no calls yet' => '没有任何来电', 'last was' => '距离上次通话时间', 'secs ago' => '秒', 'wait:' => '等待:', 'Invalid' => '无效', 'In use' => '<span style="color:#F00;">通话中</span>', 'Ringing' => '振铃中', 'ringinuse' => '');

        foreach ($arrOut as $row) {
            $trunk = substr($row['content'], 0, strpos($row['content'], ' '));
            if (false !== $arr_outqueues && !in_array($trunk, $arr_outqueues, true)) {
                continue;
            }
            $row['content'] = preg_replace('/has (\d+) calls/', '<span>有<em>$1</em>个来电等待</span>', $row['content']);
            foreach ($arrfy_content as $k => $v) {
                $row['content'] = str_replace($k, $v, $row['content']);
            }
            $sub = null;
            foreach ($row['sub'] as $item) {
                foreach ($arrfy_item as $k => $v) {
                    $item = str_replace($k, $v, $item);
                }
                $item = preg_replace('/\(\s+enabled\)/', '', $item);
// $item = preg_replace('/\(Local\/[^\)]+\)/', '', $item);
                $item = preg_replace('/has taken (\d+) calls/', '<span>累计<em>$1</em>个通话<span>', $item);
                $item = preg_replace('/\(sip\/\d+ from sip\/\d+\)/', '', $item);
                $sub[] = $item;
            }
            if (isset($sub)) {
                $row['sub'] = $sub;
            }
            $arrOut2[] = $row;
        }
        if (!$arrOut2) {
            die('队列状态中无此队列');
        }
        $temp_queues = false;
        $str = '<div class="queue-table">';
        $n = count($arrOut2);
        $i = 0;
        while ($i < $n) {
            $content = $arrOut2[$i]['content'];
            $queue = substr($content, 0, strpos($content, ' '));
            $temp_queues[] = $queue;
            $str .= '<div class="section"><div class="hd">' . $this->acdno_status_hd_format($content) . ($this->isSuperAdmin ? sprintf(' [%s]', $arrOut2[$i]['siteID']) : '') . '</div>';
            foreach ($arrOut2[$i]['sub'] as $item) {
                $item = trim($item);
                $bar = '';
                if (false !== ($pos = strpos($item, '(SIP/'))) {
                    $extension = substr($item, 0, $pos);
                    $chked = (false === strpos($item, '(示忙)')) ? '' : 'checked="checked"';
                    $bar = "<input type='checkbox' $chked data-extension='$extension' data-queue='$queue' title='示闲/示忙 (勾选=示忙,不选=示闲)' />示忙";
                }
                if ('分机:' == $item || '没有分机' == $item || '来电:' == $item || '没有来电' == $item) {
                    $str.='<div class="sub-hd">' . $item . '</div>';
                } else {
                    $str.=$this->acdno_status_item_format($item . $bar);
                }
            }
            $str .= '</div>';
            $i++;
        }
        $str .= '</div>';
//format end
        $this->assign('queues', $temp_queues);
        $this->assign('content', $str);
        $this->display($tpl);
    }

    function acdno_status_item_format($item) {
        if ('.' == $item[1]) {
//来电
            $str = "<div class='line'>$item</div>";
        } else {
// 分机
            $pos = strpos($item, ' ');
            if (false == $pos) {
                return $item;
            }
            $exten = '<em>' . substr($item, 0, $pos) . '</em> ';
            $info = substr($item, $pos + 1);
            $arrfy = array('(空闲)', '不可用');
            foreach ($arrfy as $fy) {
                $info = str_replace($fy, '<em>' . $fy . '</em>', $info);
            }

            $str = '<div class="exten">' . $exten . $info . '</div>';
        }
        return $str;
    }

// 2015-5-6
    function acdno_status_hd_format($str) {
        $pos = strpos($str, '规则 ');
        $str = substr($str, 0, $pos);
        $pos = strpos($str, ' ');
        $queue = substr($str, 0, $pos);
        $info = substr($str, $pos + 1);
        /* 2015-5-21为新增cdr记录需要,不要这些数据了
          $arrfy = array('(\d+)s holdtime', '(\d+)s talktime', 'W:(\d+)', 'C:(\d+)', 'A:(\d+)', 'within (\d+)s');
          foreach ($arrfy as $fy) {
          $info = preg_replace('/' . $fy . '/', '<span>' . str_replace('(\d+)', '<em>$1</em>', $fy) . '</span>', $info);
          }
         */
        return '<strong>' . $queue . '</strong>' . $info;
    }

    /**
     * 返回sip show peers命令结果的格式化数组(获取分机注册服务器)
     * 数组格式, 这次格式很规范了
     * 0                1               2       3           4           5      6       7            8<br />
     * Name/username    Host            Dyn    Forcerport    Comedia    ACL    Port    Status       Description<br />
     * 301/301          117.25.177.100  D       Yes          Yes        A      31145   OK(5ms)<br />
     * X81202/81202     117.25.177.99           Yes          Yes               5060    Unmonitored<br />
     *
     * @param string $summary 统计摘要
     * @param bool $fy 是否翻译
     * @return array|bool
     * @since 1.0 2014-10-31 by sutroon
     */
    function get_command_sip_show_peers_data(&$summary, $fy = false) {
        $str = $this->SCommandResult('sip show peers');
        $arr = preg_split("/[\n]+/", trim($str));
// 0_Name/username 1_Host 2_Dyn 3_Forcerport 4_ACL 5_Port 6_Status
        $n = count($arr);
        $summary = $arr[$n - 1];
        unset($arr[$n - 1]);
        $i = 0;
        $arr_hd = array('Name/username', 'Host', 'Dyn', 'Forcerport', 'ACL', 'Port', 'Status');
        $arrfy = array('Unspecified' => '未知', 'Yes' => '是', 'No' => '否', 'UNKNOWN' => '未知', 'Unmonitored' => '无监视');
        foreach ($arr as $row) {
            if ($i < 1) {
                continue;
            }
            $row = preg_replace("/OK\s+\((\d+)\s+ms\)/", "OK($1ms)", $row);
            $sub = preg_split("/[\s]+/", $row);

            if ($i < 1) {
                $row = trim($row);
            } else {
                if ($fy) {
                    foreach ($arrfy as $w => $cn) {
                        $row = str_replace($w, $cn, $row);
                    }
                }
            }
            if (count($sub) < 8) {
                if ($i < 1) {
                    array_splice($sub, 4, 0, array('Comedia'));
                    $sub[8] = 'Description';
                } else {
                    array_splice($sub, 4, 0, array(''));
                    $sub[8] = '';
                }
            }
            if (count($sub) < 9) {
// array_splice($sub, 2, 0, array(''));
                array_splice($sub, 5, 0, array(''));
            }
            if ($sub[6] == '无监视') {
                continue; // 隐藏中继
            }
            $i++;
            $arrOut[] = $sub;
        }
// 0_Name/username    1_Host            2_Dyn    3_Forcerport    4_Comedia    5_ACL    6_Port    7_Status       8_Descriptio
        return isset($arrOut) ? $arrOut : false;
    }

    /**
     * 设置或获取命令结果缓存值
     * @param $cmd
     * @return array|mixed|string
     * @since 1.0 2014-11-4
     */
    private function SCommandResult($cmd, $expire = 10) {
        $cacheId = str_replace(' ', '_', $cmd);
        $str = S($cacheId);
        if (!$str || $expire < 1) {
            $str = trim(asmanager_query_result($cmd));
            $expire = 10;
            S($cacheId, $str, array('expire' => $expire));
        }
        return $str;
    }

    private function SCommandResults($cmds, $expire = 10) {
        foreach ($cmds as $k => $cmd) {
            $cacheId = str_replace(' ', '_', $cmd);
            $str = S($cacheId);
            if (!$str || $expire < 1) {
                $str = trim(asmanager_query_result($cmd));
                $expire = 10;
                S($cacheId, $str, array('expire' => $expire));
            }
            $arr_return[$k] = $str;
        }
        return $arr_return;
    }

    /**
     * 返回sip show peers命令结果的格式化数组（获取分机在线时长、状态、主被叫号码）
     * 数组格式, 这次格式很规范了
     *  0                    1                    2                3    4       5            6                         7               8        9           10          11                  12
     *  Channel              Context              Extension        Prio State   Application  Data                      CallerID        Duration Accountcode PeerAccount BridgedTo           Phone
     * SIP/user1-00001691   my-internal                              1 Down    (None)       (None)                    05923796666     00:00:02 1.982.1.0.0             (None)
     * SIP/user1-00001678   autocall-ivr         013436063869        1 Up      AGI          autocall-ivr.php          013436063869    00:00:34 1.982.1.0.0             (None)
     * SIP/user1-00001673   my-internal                              1 Ringing (None)       (None)                    05923796666     00:00:36 1.983.1.0.0             (None)
     * SIP/user1-00001662   autocall-ivr         013436063861        1 Up      Dial         Local/2000@from-internal, 013436063861    00:00:52 1.982.1.0.0 1.982.1.0.0 SIP/304-0000168d
     * SIP/304-0000168d     from-internal                            1 Up      AppDial      (Outgoing Line)           304             00:00:09 1.982.1.0.0 1.982.1.0.0 SIP/user1-00001662   013436063861
     * @param array $arrSummary 统计摘要
     * @param bool $format 是否格式化，格式化后，Channel值SIP/304-0000168d变为304,BridgedTo=304
     * @return array|bool
     * @since 1.0 2014-9-12 by sutroon created; 2.0 2014-10-31 by sutroon 重构.
     */
    public function get_command_core_show_channels_verbose_data(&$arrSummary, $format = false) {
        $str = $this->SCommandResult('core show channels verbose');
        $arr = preg_split("/[\n]+/", $str);
        $i = 0;
        foreach ($arr as $row) {
            $row = trim($row);
            $row = preg_replace("/\((Outgoing\s+Line)\)/", "(Outgoing-Line)", $row);
            $sub = preg_split("/[\s]+/", $row);
            if ($i > 0 && false == strpos($sub[0], '/')) {
                $arrSummary[] = $row;
                continue;
            }
            if (!is_numeric($sub[3]) && $i > 0) {
                array_splice($sub, 2, 0, array(''));
            }
            if ($sub[9] == '(None)') {
                array_splice($sub, 9, 0, array('', ''));
            }
            if ($sub[10] == '(None)') {
                array_splice($sub, 10, 0, array(''));
            }
            $sub[] = '';
            $arrOut[] = $sub;
            $i++;
        }
        $extensions = S('extensions');
        if (!$extensions) {
            $extensions = M('tuser_member')->where("userType='SEAT'")->getField('extensionNumber', true);
            S('extensions', $extensions, array('expire' => 15));
        }
        if (isset($arrOut)) {
            $arrOut[0][12] = 'Phone';
            $i = 0;
            foreach ($arrOut as $row) {
                $extension = substr($row[0], 4, strpos($row[0], '-') - 4);
                if ($i > 0 && in_array($extension, $extensions)) {
                    foreach ($arrOut as $r) {
                        if ($r[11] != '(None)' && false !== strpos($r[11], 'SIP/' . $extension)) {
                            $row[12] = $r[7];
                        }
                    }
                    if (!$row[12] && $row[9]) {
                        foreach ($arrOut as $r) {
                            if ($r[9] == $row[9] && $r[7] != $row[7]) {
                                $row[12] = $r[7];
                            }
                        }
                    }
                }
                if ($format) {
                    $row[0] = $extension;
                }
                $arrOut2[] = $row;
                $i++;
            }
        }
        return isset($arrOut2) ? $arrOut2 : false;
    }

    /**
     * 
     * 分机	注册IP          NAT             设备                    Dyn	端口	注册状态	状态	持续时间	租户ID 通话号码
     * 312      117.30.135.109  192.168.0.227   FXS_GW (4asipfxs.114)   A       58350   'free'空 闲', 8 => '', 9 => '8 (华鸣茶业)', 10 => '', 11 => '', )
     * @param type $strsum
     * @return type
     */
    function get_extension_status_data(&$strsum) {
        // array('Name'=>'', 'Host'=>'', 'Dyn'=>'', 'Forcerport'=>'', 'ACL'=>'', 'Port'=>'', 'Status'=>'')
        $arr = AddonD('AgiManager')->cli_sip_show_peers(true);
        //$strsum = $arr[0];
        unset($arr[0]); // 去除统计行
        // array($name=>array('State' => '','Sort'=>0, 'Icon' => ''))
        $arr_sip_hints = AddonD('AgiManager')->cli_core_show_hints();
        // array('Channel'=>'', 'Context'=>'', 'Extension'=>'', 'Prio'=>'', 'State'=>'', 'Application'=>'', 'Data'=>'', 'CallerID'=>'', 'Accountcode'=>'', 'PeerAccount'=>'', 'What1'=>'', 'Duration'=>'', 'BridgedTo'=>'', 'Accountcode2'=>'')
        $arr_sip_duration = AddonD('AgiManager')->cli_core_show_channels_concise();
        $this->print_array($arr_sip_duration);
        foreach ($arr as $row) {
            $arrName = explode('/', $row['Name']);
            $names[] = $arrName[0];
        }
        // array($exten=>array('Reg'=>'','Useragent'=>''));
        $arr_sip_details = AddonD('AgiManager')->cli_sip_show_peer($names);
        $seats = M('tuser_member')->cache(true)->where(array('userType' => 'SEAT'))->getField('userName, personalName');
        // 分机	注册IP	NAT	设备	Dyn	端口	注册状态	状态	持续时间	租户ID        
        $arrOut = array();
        foreach ($arr as $row) {
            $arrName = explode('/', $row['Name']);
            $name = $arrName[0];
            if (!array_key_exists($name, $seats)) {
                continue;
            }
            $row_temp = array('分机' => $name . ($seats && array_key_exists($name, $seats) ? ' [' . $seats[$name] . ']' : ''), '注册IP' => $row['Host'], 'NAT' => '', '设备' => '', 'Dyn' => $row['Dyn'], '端口' => $row['Port'], '注册状态' => $row['Status'], '状态' => '', '持续时间' => '', '租户' => '', '通话号码' => '', 'exten' => $name, 'siteID' => 0);

            if (array_key_exists($name, $arr_sip_hints)) {
                $row_temp['状态'] = $arr_sip_hints[$name]['Icon'];
                $row_temp['Sort'] = $arr_sip_hints[$name]['Sort'];
            } else {
                $row_temp['状态'] = '<img data-sort="9" style="display:none;" src="#" alt="" />';
                $row_temp['Sort'] = 9;
            }
            // 2015-8-28 修正离线错误
            if ('未知' == trim($row['Status']) && '(未知)' == trim($row['Host'])) {
                $row_temp['状态'] = "<img data-sort='4' src='$icon_dir/Unavailable.png'width='11' height='10' alt='offline' />" . "离 线";
                $row_temp['Sort'] = 4;
            }
            if (is_array($arr_sip_duration)) {
                foreach ($arr_sip_duration as $rDur) {
                    if ($rDur['UserExten'] == $name) {
                        $row_temp['持续时间'] = $rDur['UserDuration'];
                        if ($rDur['Context'] == 'my-internal' && $rDur['Data'][0] == 'L') {
                            // 2015-8-24 来话导航
                            $row_temp['通话号码'] = $rDur['UserCaller'];
                        } else {
                            $row_temp['通话号码'] = $rDur['UserCalled'];
                        }
                    }
                }
            }
            if (array_key_exists($name, $arr_sip_details)) {
                $arr_extension_detail = $arr_sip_details[$name];
                $row_temp['NAT'] = $arr_extension_detail['Reg'];
                $row_temp['设备'] = $arr_extension_detail['Useragent'];
            }
            $arrOut[] = $row_temp;
        }
        if (!$arrOut) {
            return false;
        }
        //$this->print_array($arrOut);
        // 修正分机互打，被叫分机无数据的问题 2015-7-29 SoChishun Added.  
        foreach ($arrOut as $row) {
            $called = $row['通话号码'];
            if (!array_key_exists($called, $seats)) {
                for ($i = 0; $i < count($arrOut); $i++) {
                    if ($arrOut[$i]['exten'] == $called) {
                        $arrOut[$i]['持续时间'] = $row['持续时间'];
                        $arrOut[$i]['通话号码'] = $row['分机'] . '(被叫)';
                        break;
                    }
                }
            }
        }
// format end
        $seat_siteids = M('tuser_member')->cache(true)->where(array('userType' => 'SEAT'))->getField('userName, siteID');
        $trunk_siteids = M('tcti_trunk')->cache(true)->getField('account, siteID');
        $n = count($arrOut);
        for ($i = 0; $i < $n; $i++) {
            $exten = $arrOut[$i]['exten'];
            if ($arrOut[$i]['Dyn'] == '--') {
                $arrOut[$i]['状态'] = "<img data-sort='5' src='' style='display:none;' />";
            }
            if ($trunk_siteids && array_key_exists($exten, $trunk_siteids)) {
                $arrOut[$i]['租户'] = $trunk_siteids[$exten];
                $arrOut[$i]['siteID'] = $trunk_siteids[$exten];
                continue;
            }
            if ($seat_siteids && array_key_exists($exten, $seat_siteids)) {
                $arrOut[$i]['租户'] = $seat_siteids[$exten];
                $arrOut[$i]['siteID'] = $seat_siteids[$exten];
                continue;
            }
        }
        if (!$this->isSuperAdmin) {
            $n = count($arrOut);
            $siteID = $this->loginData['siteID'];
            for ($i = 0; $i < $n; $i++) {
                if ($arrOut[$i]['siteID'] !== $siteID) {
                    unset($arrOut[$i]);
                }
            }
        }

// 统计
        $sum = array('noffline' => 0, 'nfree' => 0, 'nring' => 0, 'ntalk' => 0);
        $arrsort_state = array();
        foreach ($arrOut as $key => $row) {
            $arrsort_state[$key] = $row['Sort'];
            if (strpos($row['状态'], 'offline') !== false) {
                $sum['noffline'] ++;
            } else if (strpos($row['状态'], 'free') !== false) {
                $sum['nfree'] ++;
            } else if (strpos($row['状态'], 'talk') !== false) {
                $sum['ntalk'] ++;
            } else if (strpos($row['状态'], 'ring') !== false) {
                $sum['nring'] ++;
            }
        }
        $nall = array_sum($sum);
        $strsum = '<div class="status-info"><span class="blue">分机总数<em>' . $nall . '</em></span><span class="dark-red">空闲<em>' . $sum['nfree'] . '</em></span><span class="orange">振铃<em>' . $sum['nring'] . '</em></span><span>通话<em>' . $sum['ntalk'] . '</em></span><span class="red">离线<em>' . $sum['noffline'] . '</em></span></div>';
        $arrOut = sofn_set_site_id_text($arrOut, '租户');
        array_multisort($arrsort_state, SORT_NUMERIC, SORT_ASC, $arrOut);
        $n = count($arrOut);
        return $arrOut;
    }

    function print_array($arr) {
        if (IS_AJAX) {
            return;
        }
        foreach ($arr as $key => $value) {
            echo '<hr />', $key, '<br />', var_export($value, true), '</hr />';
        }
    }

    /**
     * 获取分机状态图标
     * @return array
     * @since 1.0 2014-9-10 by sutroon
     */
    function get_sip_hints() {
        $str = $this->SCommandResult('core show hints');
        $values = explode("\n", $str);
        $arr = array();
        foreach ($values as $val) {
            if (preg_match('/State:/', $val)) {
//echo $val."</br>";
                $sip_name = explode("@", $val);
                $name = trim($sip_name[0]);
                if ($name[0] == '*') {
                    continue;
                }
//echo $sip_name[0]."</br>";
                $sip_sb = explode(":", $val);
                $sip_zsb = explode("State", $sip_sb[1]);
//echo $sip_zsb[0];
                $sip_zt = explode("State:", $val);
                $sip_zzt = explode("Watchers", $sip_zt[1]);
//echo $sip_zzt[0];
//...
                if (preg_match('/Unavailable/', $sip_zzt[0])) {
                    $sip_zzt[0] = "<img data-sort='4' src='$icon_dir/Unavailable.png'width='11' height='10' alt='offline' />" . "离 线";
                } else if (preg_match('/Idle/', $sip_zzt[0])) {
                    $sip_zzt[0] = "<img data-sort='3' src='$icon_dir/Idle.png' alt='free' />" . "空 闲";
                } else if (preg_match('/Busy/', $sip_zzt[0]) || preg_match('/InUse/', $sip_zzt[0])) {
                    $sip_zzt[0] = "<img data-sort='1' src='$icon_dir/InUse.png' width='17' height='17' alt='talk' />" . "通 话";
                } else if (preg_match('/Ringin/', $sip_zzt[0])) {
                    $sip_zzt[0] = "<img data-sort='2' src='$icon_dir/Ringing.png' alt='ring' />" . "振 铃";
                }
                $arr[] = array($name, $sip_zzt[0]);
            }
        }
        return $arr;
    }

    /**
     * 获取分机注册NAT和设备名称
     * @param $extension
     * @return array
     * @since 1.0 2014-9-24 by sutroon
     */
    function get_extension_detail($extension) {
        $str = $this->SCommandResult('sip show peer ' . $extension);
        $arr = preg_split("/\n/", trim($str));
        $arrRow = null;
        $arrOut = array();
        foreach ($arr as $row) {
            $arrRow = explode(':', $row, 2);
            if (trim($arrRow[0]) == 'Useragent') {
                $arrOut['Useragent'] = $arrRow[1];
                continue;
            }
            if (trim($arrRow[0]) == 'Reg. Contact') {
                $arrRow[1] = substr($arrRow[1], strpos($arrRow[1], '') + 1);
                $arrRow[1] = substr($arrRow[1], 0, strpos($arrRow[1], ':'));
                $arrOut['Reg'] = $arrRow[1];
                continue;
            }
        }
        return $arrOut;
    }

// 2014-11-6 by sutroon
    function get_extension_details($extensions) {
        foreach ($extensions as $extension) {
            $cmds[$extension] = 'sip show peer ' . $extension;
        }
        $returns = $this->SCommandResults($cmds);
        foreach ($returns as $k => $str) {
            $arr = preg_split("/\n/", trim($str));
            $arrRow = null;
            $arrOut = array();
            foreach ($arr as $row) {
                $arrRow = explode(':', $row, 2);
                if (trim($arrRow[0]) == 'Useragent') {
                    $arrOut['Useragent'] = $arrRow[1];
                    continue;
                }
                if (trim($arrRow[0]) == 'Reg. Contact') {
                    $arrRow[1] = substr($arrRow[1], strpos($arrRow[1], '') + 1);
                    $arrRow[1] = substr($arrRow[1], 0, strpos($arrRow[1], ':'));
                    $arrOut['Reg'] = $arrRow[1];
                    continue;
                }
            }
            $arr_return[$k] = $arrOut;
        }
        return $arr_return;
    }

// 获取速度控件 2014-10-29 by sutroon
// $this->get_speed_control($tsid, $data['speedMode'], $data['speed'], $data['trunkName'])
    private function get_speed_control($tsid, $speedMode, $speed, $trunkName) {
        $summary = '外呼速度:<em>(' . get_speedMode_text($speedMode) . ')';
        if ($speedMode == 'channel') {
            $regNumber = M('tcti_trunk')->where("account='" . $trunkName . "'")->getField('regNumber');
            $select = '<select id="speed" data-update-url="' . AddonU('TaskStrategy/set_speed', 'show=dialog&speed=varspeed&id=' . $tsid) . '">';
            for ($i = 1; $i <= $regNumber; $i++) {
                $select .= "<option value='$i'" . ($i == $speed ? ' selected="selected"' : '') . ">$i</option>";
            }
            $select .= '</select>';
            $summary .= $select;
        } else {
            $summary .= '1:<input type="text" size="3" id="speed" value="' . $speed . '" data-update-url="' . AddonU('TaskStrategy/set_speed', 'show=dialog&speed=varspeed&id=' . $tsid) . '" />';
        }
        return $summary;
    }

    public function system_restart_service() {
        $type = I('type');
        switch ($type) {
            case 'web':
                $type = 'httpd';
                break;
            case 'db':
                $type = 'mysqld';
                break;
            case 'cti':
                $type = 'asterisk';
                break;
            default:
                $type = '';
                break;
        }
        if ($type) {
            $msg = system("service $type restart", $code);
            die($code . ':' . $msg);
        }
        die('done!');
    }

// 检测cti是否重名 2014-12-1 by sutroon
    public function cti_check_extension($extension = false) {
        $msg = self::cti_check_extension_func($extension);
        if (true === $msg) {
            $this->ajaxMsg(true, $extension);
        } else {
            $this->ajaxMsg(false, $msg);
        }
    }

// 检测cti是否重名 2014-12-1 by sutroon
    public static function cti_check_extension_func($extension = false) {
        if (!$extension) {
            return '参数有误';
        }
        // xcall-keyword
        if ($extension[0] == '7') {
            return '分机号以7开头将和系统关键代码冲突';
        }
        $M = M();
// queues_check_extensions
        $sql = "SELECT extension, descr FROM asterisk.queues_config WHERE extension = '$extension' limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被队列使用: " . $result[0]['descr'];
            return $msg;
        }
// 分机
        $sql = "SELECT extension FROM asterisk.users where extension='$extension' limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被分机使用: " . $result[0]['extension'];
            return $msg;
        }

// 会议
        $sql = "SELECT exten FROM asterisk.meetme WHERE exten ='$extension' limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被会议使用: " . $result[0]['exten'];
            return $msg;
        }

// customappsreg_check_extensions
        $sql = "SELECT custom_exten, description FROM asterisk.custom_extensions WHERE custom_exten = '$extension' limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被自定义分机使用: " . $result[0]['description'];
            return $msg;
        }

// featurecodeadmin_check_extensions
        $sql = "SELECT featurecodes.modulename, featurecodes.featurename, featurecodes.description AS featuredescription, featurecodes.enabled AS featureenabled, featurecodes.defaultcode, featurecodes.customcode,modules.enabled AS moduleenabled, featurecodes.providedest FROM asterisk.featurecodes INNER JOIN asterisk.modules ON modules.modulename = featurecodes.modulename where featurecodes.enabled=1 and modules.enabled=1 and (featurecodes.customcode='$extension' or featurecodes.defaultcode='$extension') ORDER BY featurecodes.modulename, featurecodes.description limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被系统关键词使用: " . $result[0]['featurename'] . " (" . $result[0]['modulename'] . ":" . $result[0]['featuredescription'] . ")";
            return $msg;
        }

// paging_check_extensions
        $sql = "SELECT page_group, description FROM asterisk.paging_config WHERE page_group = '$extension' limit 1;";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被PageGroup使用: " . $result[0]['description'];
            return $msg;
        }

// parking_check_extensions ParkPlus: ParkCall %s
        $sql = "SELECT name,parkext,parkpos,numslots FROM asterisk.parkplus WHERE defaultlot = 'yes' and parkext = '$extension' LIMIT 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被ParkPlus使用: ParkCall " . $result[0]['name'];
            return $msg;
        }

// ringgroups_check_extensions
        $sql = "SELECT grpnum ,description FROM asterisk.ringgroups WHERE grpnum = '$extension' limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被Ring Group使用: " . $result[0]['description'];
            return $msg;
        }

// sng_mcu_check_extensions Sangoma MCU Host: %s, Name: %s Ext: %s
        $sql = "SELECT * FROM asterisk.sng_mcu_entries  WHERE `sng_mcu_id` = '$extension' limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = sprintf("已被Sangoma MCU使用 Name: %s Ext: %s", $result[0]['name'], $result[0]['ext']);
            return $msg;
        }

// vmblast_check_extensions
        $sql = "SELECT grpnum, description FROM asterisk.vmblast WHERE grpnum = '$extension' limit 1";
        $result = $M->query($sql);
        if ($result) {
            $msg = "已被语音信箱使用: " . $result[0]['description'];
            return $msg;
        }
        return true;
    }

}
